Figure~\ref{fig:parallelism} is a representation of how the framework has been
implemented in terms of multi-threading.

\begin{figure*}[t]
\centering
\begin{tikzpicture}
\tikzstyle{thread-pool} = [draw=black, rectangle]

\tikzstyle{bigbox} = [draw, rounded corners, rectangle]
\tikzstyle{boxed} = [minimum height=0.8cm, draw=black!50, rounded corners,rectangle] 
\tikzstyle{unboxed} = [minimum height=0.8cm,rounded corners,rectangle] 
\tikzstyle{node}=[circle,minimum size=10pt,draw=black, font=\tiny ] 
\tikzstyle{blind}=[]
\tikzstyle{title} =[fill=white, text=black!80]
\tikzstyle{edge} = [->,text=black]

\node[draw, rounded corners, rectangle, minimum width=55pt,minimum height=20pt]
(1-measure-pattern) {};

\node[draw,rounded corners,rectangle,minimum width=55pt,minimum
height=20pt,below=10pt of 1-measure-pattern] (top-k-pattern) {};
\node[title,right=5pt] at (top-k-pattern.north west) {Top-k};
\node[draw,rounded corners, rectangle,minimum width=55pt,minimum
height=20pt,below=10pt of top-k-pattern] (additional-patterns) {};
\node[title,right=5pt] at (additional-patterns.north west) {\ldots};
\node[blind,above=10pt of 1-measure-pattern] (pattern-executor-space-1) {};
\node[draw,rectangle,minimum width=50pt,minimum
height=20pt,fit=(pattern-executor-space-1)(1-measure-pattern)(top-k-pattern)(additional-patterns)]
(pattern) {};
\node[title,below=2pt] at (pattern.north) {Patterns};

\node[title,right=5pt] at (1-measure-pattern.north west) {1-Measure};


\node[draw, rounded corners, rectangle,minimum height=120pt,minimum
width=80pt,fit=(pattern)]
(pattern-executor) {}; 

\node[title,right=5pt] at (pattern-executor.north west) (pattern-executor-title)
{Pattern executor}; 


\node[draw, rounded corners,rectangle,right=10pt of
pattern-executor,thread-pool,minimum height=120pt,minimum
width=80pt,right=10pt of pattern-executor]
(object-wrapper) {};

\node[title,right=5pt]
at (object-wrapper.north west) (object-wrapper-title) {Object wrapper};

\node[draw,rectangle,minimum width=65pt,minimum
height=105pt,below=10pt] at (object-wrapper.north)
(internal-queries) {};

\node[title,below=2pt] at (internal-queries.north) (internal-queries-title)
{Internal queries};

\node[draw,rounded corners,rectangle,minimum width=50pt,minimum
height=20pt,below=20pt] at (internal-queries-title.north) (query-1) {};

\node[title,right=5pt] at (query-1.north west) (query-1-title) {Query 1};

\node[draw,rounded corners,rectangle,minimum width=50pt, minimum
height=20pt,below=30pt] at (query-1.north) (query-2) {};

\node[title,right=5pt] at (query-2.north west) (query-2-title) {Query 2};

\node[draw,rounded corners,rectangle,minimum width=50pt, minimum
height=20pt,below=30pt] at (query-2.north) (query-n) {};

\node[title,right=5pt] at (query-n.north west) (query-n-title) {\ldots};

\node[draw,rounded corners,rectangle,right=10pt of
object-wrapper,thread-pool,minimum height=120pt,minimum width=100pt]
(query-scheduler) {}; 

\node[title,right=5pt] at (query-scheduler.north west) (query-scheduler-title)
{Query scheduler};

\node[draw,rectangle,minimum width=90pt,minimum height=105pt,below=10pt] at
(query-scheduler.north) (database-queries) {};

\node[title,below=2pt] at (database-queries.north) (database-queries-title)
{Database queries};

\node[draw,rounded corners,rectangle,minimum width=80pt, minimum
height=20pt,below=20pt] at (database-queries.north) (database-query-1) {};

\node[title,right=5pt] at (database-query-1.north west) {Database query 1};

\node[draw,rounded corners, rectangle,minimum width=80pt,minimum
height=20pt,below=30pt] at (database-query-1.north) (database-query-2) {};

\node[title,right=5pt] at (database-query-2.north west) {Database query 2};

\node[draw,rounded corners, rectangle,minimum width=80pt,minimum
height=20pt,below=30pt] at (database-query-2.north) (database-query-n) {};

\node[title,right=5pt] at (database-query-n.north west) {Database query $n$};

\node[blind,above=0pt of pattern-executor] (hspace1) {};
\node[bigbox,fit=(hspace1)(pattern-executor)(object-wrapper)(query-scheduler),minimum
width=290pt](pattern-search-plugin) {}; 
\node[title, right=10pt] at (pattern-search-plugin.north west) {Pattern search plugin};

\node[blind,above=10pt of pattern-search-plugin] (hspace2) {};
\node[bigbox,below=10pt of
pattern-search-plugin,minimum width=290,minimum
height=20pt](other-search-plugins){};
\node[title,right=10pt] at (other-search-plugins.north west) {Other search
plugins};
\node[draw,fit=(hspace2)(pattern-search-plugin)(other-search-plugins),minimum
width=300pt,minimum height=190] (search-plugins) {}; \node[title, below=2pt] at
(search-plugins.north) {Search plugins};

\node[draw,rectangle,minimum width=300pt,minimum height=50pt,below=10pt] at
(search-plugins.south) (answer-plugins) {};
\node[title,below=3pt] at (answer-plugins.north) {Answer plugins};

\node[draw,rounded corners,rectangle,minimum width=50pt,minimum
height=20pt,below=20pt] at (answer-plugins.north) (result-2) {};

\node[title,right=5pt] at (result-2.north west) {Result 2};

\node[draw,rounded corners,rectangle,minimum width=50pt,minimum
height=20pt,left=50pt] at (result-2.west) (result-1) {};

\node[title, right=5pt] at (result-1.north west) {Result 1};

\node[draw,rounded corners,rectangle,minimum width=50pt,minimum
height=20pt,right=40pt] at (result-2.east) (result-n) {};

\node[title,right=5pt] at (result-n.north west) {Result $n$};

\node[blind,above=0pt of search-plugins] (search-executor-space-1) {};

\node[blind,below=0pt of answer-plugins] (search-executor-space-2) {};
\node[draw,rounded
corners,rectangle,fit=(search-executor-space-1)(search-plugins)(answer-plugins)(search-executor-space-2),inner
xsep=10pt,minimum height=270pt] (search-executor) {};

\node[title,right=5pt] at (search-executor.north west) {Search executor};

\node[draw, rounded corners,rectangle, minimum width=80pt,minimum
height=270pt,left=10pt] at (search-executor.west) (query-builder) {};

\node[title,right=5pt] at (query-builder.north west) {Query builder};

\node[draw,rounded corners,rectangle,minimum width=40pt,minimum
height=270pt,left=10pt] at (query-builder.west) (search-service) {};

\node[title,below=35pt,rotate=90,yshift=7pt] at (search-service.north west)
{Search service};

\node[draw,rectangle,minimum width=70pt,minimum height=190pt,below=10pt] at
(query-builder.north) (query-plugins) {};

\node[title,below=2pt] at (query-plugins.north) {Query plugins};

\node[draw,rounded corners,rectangle,minimum width=60pt,minimum
height=20pt,below=40pt] at (query-plugins.north) (plugin-1) {};

\node[title,right=5pt] at (plugin-1.north west) {NLP feature};

\node[draw,rounded corners,rectangle,minimum width=60pt,minimum
height=20pt,below=30pt] at (plugin-1) (plugin-2) {};

\node[title,right=5pt] at (plugin-2.north west) {Census};

\node[draw,rounded corners,rectangle,minimum width=60pt,minimum
height=20pt,below=30pt] at (plugin-2) (plugin-n) {};

\node[title,right=5pt] at (plugin-n.north west) {\ldots};

\node[blind,fit=(search-service)(query-builder)(search-executor)] (all) {};

\node[draw,rectangle,below=5pt,minimum width=300pt, minimum height=40pt] at
(all.south) (legend) {};

\node[title,right=5pt,yshift=-8pt] at (legend.north west) {Legend};

\path[edge,bend left] (pattern) edge node {} (internal-queries);

\path[edge,bend left] (internal-queries) edge node {} (database-queries);

\path[edge,bend left,very thick,dashed] (search-service) edge node {}
(search-executor); 

\path[edge,bend left,very thick,dashed] (search-plugins) edge node {}
(answer-plugins);

\node[draw,rounded corners,rectangle,minimum width=50pt, minimum
height=20pt,right=40pt] at (legend.west) (thread) {};

\node[title,right=5pt] at (thread.north west) {Thread};

\node[draw,rectangle,minimum width=50pt,minimum height=20pt,right=10pt] at
(thread.east) (thread-pool) {};

\node[title,below=2pt] at (thread-pool.north) {Thread pool};

\node[right=15pt] at (thread-pool.east) (point1) {};

\node[right=20pt] at (point1) (point2) {};

\path[edge, bend left] (point1) edge node[below] {Ordered queue} (point2);

\node[right=30pt] at (point2.east) (point3) {};

\node[right=20pt] at (point3.east) (point4) {};

\path[edge, bend left, very thick, dashed] (point3) edge node[below] {Calls
with queue} (point4);
\end{tikzpicture}
\caption{Overview of the threads involved in the parallel implementation of the
framework}
\label{fig:parallelism}
\end{figure*} 

For the sake of clarity, we have simplified the diagram: there are more patterns
and plugins (additional components are marked with ``\ldots'').



